package com.foreveross.proxyip.remote;

import java.io.Serializable;
import java.util.List;

import javax.annotation.Resource;

import org.apache.commons.lang.exception.ExceptionUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;

import com.foreveross.crawl.common.cfg.PropertyUtils;
import com.foreveross.proxyip.IProxyIpProvider;
import com.foreveross.proxyip.ProxyIpModel;
import com.foreveross.proxyip.ProxyipProperties;

/**
 * 代理IP提供者实现
 * <p>这是一个代理IP提供者的综合策略实现，采用多种方式取得代理IP,
 * 当第一种方式取得不成功时，则采用第二种
 * <p>一般地，代理IP由远端服务协议提供，比如rmi, ejb, webservice等,在这里
 * 我们采用多个配置，多个IP的方式取代理IP,同时支持本地代理IP池(见<code>LocalProxyIpProvider</code>)获取
 * @author xiangsf 2013-06-09
 *
 */
@Component("proxyIpProviderImpl")
public class ProxyIpProviderImpl implements IProxyIpProvider {

	public Logger logger = LoggerFactory.getLogger(ProxyIpProviderImpl.class);
	@Resource(name="rmiProxyIpProvider")
	private IProxyIpProvider proxyIPRMIService;
	
	@Resource(name="localProxyIpProvider")
	private IProxyIpProvider localProxyIpProvider;

	@Override
	public synchronized ProxyIpModel provideProxyIp() {
		int repeatCount=PropertyUtils.getIntProperty(
				ProxyipProperties.PROXY_IP_PROVIDER_REPRATCOUNT, ProxyipProperties.CONFIG_FILE,5);
		int interval=PropertyUtils.getIntProperty(
				ProxyipProperties.PROXY_IP_PROVIDER_REPRATINTERVAL, ProxyipProperties.CONFIG_FILE,1000);
		ProxyIpModel ipModel = null;
		long l=System.currentTimeMillis();
		while(repeatCount-->0){
			try{
				ipModel = proxyIPRMIService.provideProxyIp();
				if(ipModel!=null){
					logger.info(String.format("渠道从远程代理取得IP[%s],耗时[%s]毫秒", ipModel.getProxyIp(),System.currentTimeMillis()-l));
					break;
				}
				Thread.sleep(interval);
			}catch(Exception e){
				logger.error(String.format("渠道[%s]获取IP 异常\n[%s]",ExceptionUtils.getFullStackTrace(e)));
			}
		}
		if(ipModel==null){
			logger.info(String.format("远程代理[%s]次拿不到IP,本次切换为本地",
						PropertyUtils.getIntProperty(
								ProxyipProperties.PROXY_IP_PROVIDER_REPRATCOUNT, ProxyipProperties.CONFIG_FILE,5)));
			ipModel = localProxyIpProvider.provideProxyIp();
		}
		return ipModel;
	}
	@Override
	public synchronized ProxyIpModel provideProxyIp(Serializable channelId) {
		int repeatCount=PropertyUtils.getIntProperty(
				ProxyipProperties.PROXY_IP_PROVIDER_REPRATCOUNT, ProxyipProperties.CONFIG_FILE,5);
		int interval=PropertyUtils.getIntProperty(
				ProxyipProperties.PROXY_IP_PROVIDER_REPRATINTERVAL, ProxyipProperties.CONFIG_FILE,1000);
		ProxyIpModel ipModel = null;
		long l=System.currentTimeMillis();
		while(repeatCount-->0){
			try{
				ipModel = proxyIPRMIService.provideProxyIp(channelId);
				if(ipModel!=null){
					logger.info(String.format("渠道[%s]从远程代理取得IP[%s],耗时[%s]毫秒", ipModel.getProxyIp(), channelId,System.currentTimeMillis()-l));
					break;
				}
				Thread.sleep(interval);
			}catch(Exception e){
				logger.error(String.format("渠道[%s]获取IP 异常\n[%s]", channelId,ExceptionUtils.getFullStackTrace(e)));
			}
		}
		if(ipModel==null){
			logger.info(String.format("远程代理[%s]次拿不到IP,本次切换为本地",
						PropertyUtils.getIntProperty(
								ProxyipProperties.PROXY_IP_PROVIDER_REPRATCOUNT, ProxyipProperties.CONFIG_FILE,5)));
			ipModel = localProxyIpProvider.provideProxyIp();
		}
		return ipModel;
	}
	
	@Override
	public synchronized void rollBackProxyIp(ProxyIpModel model) {
			proxyIPRMIService.rollBackProxyIp(model);
		
			localProxyIpProvider.rollBackProxyIp(model);
	}

	@Override
	public List<ProxyIpModel> provideProxyIps() {
		return proxyIPRMIService.provideProxyIps();
	}
	@Override
	public List<ProxyIpModel> provideProxyIps(Serializable channelId) {
		return proxyIPRMIService.provideProxyIps(channelId);
	}
}
